/**************************************************************************************
Class Name              : CaseTriggerHandler_AC
Created By              : Kalyani Nemala
Created on              : 01/21/2013
Description             : Updated the method - onCaseTypeUpdate. Accepts Case Type Name as input paramaeters for the
                          method onCaseTypeUpdate and returns the Case categorization details, Queue name, Priority as ouput.
Version                 : 1.0
***************************************************************************************
Updated By              : Kalyani Nemala
Created on              : 01/30/2013
Description             : Updated the case owner Id
Version                 : 1.1
***************************************************************************************
Updated By              : Kalyani Nemala
Created on              : 02/06/2013
Description             : Updated the Email to case set up details 
Version                 : 1.2
***************************************************************************************/
public with sharing class CaseTriggerHandler_AC {
    private boolean m_isExecuting = false;
    private integer BatchSize = 0;
    private Map<String, QueueSobject> mapQueueReferenceObject = new Map<String, QueueSobject>();  
    private Map<String,West_Case_Names__c> mapCaseCustSettingReferenceObject = new Map<String,West_Case_Names__c>();
    private Map<String,West_Case_Type__c> mapCaseEmailTemplateText = new Map<String,West_Case_Type__c>();
    private Map<String, String> mapEmailIds = new Map<String, String>();
    public CaseTriggerHandler_AC(){
         for(QueueSobject listQueueReferenceType : [SELECT Id, QueueId, Queue.Name FROM QueueSobject WHERE SobjectType = 'Case']){
                                                   mapQueueReferenceObject.put(listQueueReferenceType.Queue.Name, listQueueReferenceType);  
                                                   }
                                                   
                                                   
         mapCaseCustSettingReferenceObject = West_Case_Names__c.getAll();
                                                   
         for(West_Case_Type__c objCaseType:[SELECT West_Case_Type_Field__c,Initial_Response_Template_Body__c,Closed_Response_Template_Body__c,Auto_Case_Initial_Email_Subject__c,Auto_Case_Closed_Email_Subject__c FROM West_Case_Type__c]){
                mapCaseEmailTemplateText.put(objCaseType.West_Case_Type_Field__c, objCaseType); 
         }    
         //Added by Metasts for analysis
               System.Debug('mapQueueReferenceObject+++++++++++++++++++++++++'+mapQueueReferenceObject);
               System.Debug('mapCaseCustSettingReferenceObject+++++++++++++++++++++++++'+mapCaseCustSettingReferenceObject);
               System.Debug('mapCaseEmailTemplateText+++++++++++++++++++++++++'+mapCaseEmailTemplateText);
               
               //end by Metasts                                      
    }
    public void OnBeforeUpdate(List<Case> newUpdatedCasesMap ,Map<Id, Case> oldUpdatedCasesMap ){
        for(Integer i=0;i<newUpdatedCasesMap.size();i++){  
            if(newUpdatedCasesMap[i].Case_RecordTypeName__c == 'CMS'){
                if(newUpdatedCasesMap[i].Status == 'Pending Acceptance' && 
                        oldUpdatedCasesMap.get(newUpdatedCasesMap[i].Id).Status != 'Pending Acceptance'){   
                    newUpdatedCasesMap[i].Status_Pending_Date__c = system.now();
                    newUpdatedCasesMap[i].Status_Research_Date__c = null;
                    newUpdatedCasesMap[i].Status_Resolution_Date__c = null;
                }  
                if(newUpdatedCasesMap[i].Status == 'Research' && 
                        oldUpdatedCasesMap.get(newUpdatedCasesMap[i].Id).Status != 'Research'){
                    newUpdatedCasesMap[i].Status_Pending_Date__c = null;
                    newUpdatedCasesMap[i].Status_Research_Date__c = system.now();
                    newUpdatedCasesMap[i].Status_Resolution_Date__c = null;
                }
                if(newUpdatedCasesMap[i].Status == 'Resolution' && 
                        oldUpdatedCasesMap.get(newUpdatedCasesMap[i].Id).Status != 'Resolution'){
                    newUpdatedCasesMap[i].Status_Pending_Date__c = null;
                    newUpdatedCasesMap[i].Status_Research_Date__c = null;
                    newUpdatedCasesMap[i].Status_Resolution_Date__c = system.now();
                }
                newUpdatedCasesMap[i].Owner_Name__c = newUpdatedCasesMap[i].Owner.Name; 
            }
        }
    }
    
    public void onBeforeInsert(List<Case> newUpdatedCasesMap){
        
        for(Integer i=0;i<newUpdatedCasesMap.size();i++){ 
      //         EmailfromleadorAccount(newUpdatedCasesMap[i]);
            if(newUpdatedCasesMap[i].Case_RecordTypeName__c == 'CMS'){
                newUpdatedCasesMap[i].Owner_Name__c = newUpdatedCasesMap[i].Owner.Name; 
                
               //Added by Metasts for analysis
               System.Debug('Owner_Name__c+++++++++++++++++++++++++'+newUpdatedCasesMap[i].Owner_Name__c);
               //end by Metasts 
            }
            
        }
    }
    public void onUpdateCase(list<Case> newCaseDetailsToUpdate){ 
         /* Record types for the West Case Support and West ADA Case Support */
        String westCaseRecordType = Schema.Sobjecttype.Case.getRecordTypeInfosByName().get('West - Support').getRecordTypeId();
        String westAdaCaseRecordType = Schema.Sobjecttype.Case.getRecordTypeInfosByName().get('West - ADA Support').getRecordTypeId();
 
            West_Case_Names__c objCustSettingCaseNameToUpdate;  
                          
            /* If the Case name is not changed only upon Transfer change the Status */
             /* Iterate through the updated values  */
             for(Case objUpdateCase : newCaseDetailsToUpdate){
            /* Check for the West Support Case record type & West ADA Case record type */
                   if(objUpdateCase.RecordTypeId == westCaseRecordType ||objUpdateCase.RecordTypeId == westAdaCaseRecordType  ){
                        objCustSettingCaseNameToUpdate = mapCaseCustSettingReferenceObject.get(objUpdateCase.Case_Name__c);
                       if(mapQueueReferenceObject.containsKey(objUpdateCase.Queue_Name__c)){
                                if(objUpdateCase.Status=='Transferred' || objUpdateCase.Status=='New')
                                    objUpdateCase.OwnerId = mapQueueReferenceObject.get(objUpdateCase.Queue_Name__c).QueueId;
                             }      
                }
              }
    }
        public void onUpdateCaseDetails(list<Case> newCaseUpdateDetailsMap){
        /* Record types for the West Case Support and West ADA Case Support */
        String westCaseRecordType = Schema.Sobjecttype.Case.getRecordTypeInfosByName().get('West - Support').getRecordTypeId();
        String westAdaCaseRecordType = Schema.Sobjecttype.Case.getRecordTypeInfosByName().get('West - ADA Support').getRecordTypeId();
            West_Case_Names__c objCustSettingCaseNameUpdate;  
                           
            /*Iterate through the Map values      */        
            for(Case objCaseUpdate : newCaseUpdateDetailsMap){
                
                /*Check for the West Support Case record type & West ADA Case record type*/
                if(objCaseUpdate.Case_Name__c !='' && (objCaseUpdate.RecordTypeId == westCaseRecordType ||objCaseUpdate.RecordTypeId == westAdaCaseRecordType)){
                objCustSettingCaseNameUpdate = mapCaseCustSettingReferenceObject.get(objCaseUpdate.Case_Name__c);
                System.debug('Case Name: '+objCaseUpdate.Case_Name__c +' and Value from map is: '+objCustSettingCaseNameUpdate);
                /*Update the Case Categorization details - Group, Category, Activity, Queue Name, Autoresponse flags & Priority*/
                    objCustSettingCaseNameUpdate = mapCaseCustSettingReferenceObject.get(objCaseUpdate.Case_Name__c);
                    System.debug('Cases details have been updated');    
                objCaseUpdate.Case_Name__c = objCustSettingCaseNameUpdate.Name;
                objCaseUpdate.Group__c  = objCustSettingCaseNameUpdate.West_Case_Group__c;
                objCaseUpdate.Category__c = objCustSettingCaseNameUpdate.West_Case_Name_Category__c;
                objCaseUpdate.Activity__c = objCustSettingCaseNameUpdate.West_Case_Name_Activity__c;
                objCaseUpdate.Queue_Name__c = objCustSettingCaseNameUpdate.West_Queue_Name__c;
                objCaseUpdate.West_Case_Auto_Initial_Response__c = objCustSettingCaseNameUpdate.West_Case_Auto_Initial__c;
                objCaseUpdate.West_Case_Auto_Close_Response__c   = objCustSettingCaseNameUpdate.West_Case_Auto_Close__c; 
                objCaseUpdate.West_Case_Deadline__c = objCustSettingCaseNameUpdate.West_Case_Type_Deadline__c;
                objCaseUpdate.Manual_Intervention_Not_Required__c = objCustSettingCaseNameUpdate.West_Case_No_Manual_Intervention__c;
                
                if(objCustSettingCaseNameUpdate.West_Case_Auto_Initial__c && mapCaseEmailTemplateText.containsKey(objCustSettingCaseNameUpdate.Name)){
                    objCaseUpdate.Initial_Response_Template_Body__c = parseMergeFields(mapCaseEmailTemplateText.get(objCustSettingCaseNameUpdate.Name).Initial_Response_Template_Body__c,objCaseUpdate);
                    objCaseUpdate.Auto_Case_Initial_Email_Subject__c = parseMergeFields(mapCaseEmailTemplateText.get(objCustSettingCaseNameUpdate.Name).Auto_Case_Initial_Email_Subject__c,objCaseUpdate);
                }
                if(objCustSettingCaseNameUpdate.West_Case_Auto_Close__c && mapCaseEmailTemplateText.containsKey(objCustSettingCaseNameUpdate.Name)){
                    objCaseUpdate.Closed_Response_Template_Body__c = parseMergeFields(mapCaseEmailTemplateText.get(objCustSettingCaseNameUpdate.Name).Closed_Response_Template_Body__c,objCaseUpdate);
                    objCaseUpdate.Auto_Case_Closed_Email_Subject__c = parseMergeFields(mapCaseEmailTemplateText.get(objCustSettingCaseNameUpdate.Name).Auto_Case_Closed_Email_Subject__c,objCaseUpdate);
                }
               /* If the Case Priority is not set, update it. */   
               if(objCaseUpdate.West_Case_Priority_Set__c == false){
                objCaseUpdate.Priority = objCustSettingCaseNameUpdate.West_Case_Priority__c;
                objCaseUpdate.West_Case_Priority_Set__c = true;
               }
                
             /* Update Owner Id */
             if(mapQueueReferenceObject.containsKey(objCaseUpdate.Queue_Name__c)){
                if(objCaseUpdate.Status=='New' || objCaseUpdate.Status=='Transferred')
                        objCaseUpdate.OwnerId = mapQueueReferenceObject.get(objCaseUpdate.Queue_Name__c).QueueId;
             }
  
          }
        }      
    }
   
    public void onCreateCase(list<Case> newCaseDetailsMap){
        /* Record types for the West Case Support and West ADA Case Support */
        String westCaseRecordType = Schema.Sobjecttype.Case.getRecordTypeInfosByName().get('West - Support').getRecordTypeId();
        String westAdaCaseRecordType = Schema.Sobjecttype.Case.getRecordTypeInfosByName().get('West - ADA Support').getRecordTypeId();
        West_Case_Names__c objCustSettingCaseName;  
           
             
              /*Iterate through the Map values      */        
            for(Case objCase : newCaseDetailsMap){
    
            /*Check for the West Support Case record type & West ADA Case record type*/
                if(objCase.Case_Name__c != null && objCase.Case_Name__c !='' && (objCase.RecordTypeId == westCaseRecordType ||objCase.RecordTypeId == westAdaCaseRecordType)){
                objCustSettingCaseName = mapCaseCustSettingReferenceObject.get(objCase.Case_Name__c);
       
                /*Update the Case Categorization details - Group, Category, Activity, Queue Name, Autoresponse flags & Priority*/
             /*   if(objCase.Origin == 'Email'){
                    objCustSettingCaseName = mapCaseCustSettingReferenceObject.get('Miscellaneous');    
                }
                else{
                    objCustSettingCaseName = mapCaseCustSettingReferenceObject.get(objCase.Case_Name__c);
                } */ //Commented by Kalyani
                 objCustSettingCaseName = mapCaseCustSettingReferenceObject.get(objCase.Case_Name__c);
             //   else{
                System.debug('Cases details have been updated');     
                objCase.Case_Name__c = objCustSettingCaseName.Name;
                objCase.Group__c    = objCustSettingCaseName.West_Case_Group__c;
                objCase.Category__c = objCustSettingCaseName.West_Case_Name_Category__c;
                objCase.Activity__c = objCustSettingCaseName.West_Case_Name_Activity__c;
                objCase.Queue_Name__c = objCustSettingCaseName.West_Queue_Name__c;
                objCase.West_Case_Auto_Initial_Response__c = objCustSettingCaseName.West_Case_Auto_Initial__c;
                objCase.West_Case_Auto_Close_Response__c   = objCustSettingCaseName.West_Case_Auto_Close__c;
                objCase.West_Case_Deadline__c = objCustSettingCaseName.West_Case_Type_Deadline__c;
                objCase.Manual_Intervention_Not_Required__c = objCustSettingCaseName.West_Case_No_Manual_Intervention__c;
                
                if(objCustSettingCaseName.West_Case_Auto_Initial__c && mapCaseEmailTemplateText.containsKey(objCustSettingCaseName.Name)){
                    objCase.Initial_Response_Template_Body__c = parseMergeFields(mapCaseEmailTemplateText.get(objCustSettingCaseName.Name).Initial_Response_Template_Body__c,objCase);
                    objCase.Auto_Case_Initial_Email_Subject__c = parseMergeFields(mapCaseEmailTemplateText.get(objCustSettingCaseName.Name).Auto_Case_Initial_Email_Subject__c,objCase);
                    //Added by Metasts for analysis
               System.Debug('objCase.Initial_Response_Template_Body__c+++++++++++++++++++++++++'+objCase.Initial_Response_Template_Body__c);
               System.Debug('objCase.Auto_Case_Initial_Email_Subject__c+++++++++++++++++++++++++'+objCase.Auto_Case_Initial_Email_Subject__c);
               
               //end by Metasts
                 }
                if(objCustSettingCaseName.West_Case_Auto_Close__c && mapCaseEmailTemplateText.containsKey(objCustSettingCaseName.Name)){
                    objCase.Closed_Response_Template_Body__c = parseMergeFields(mapCaseEmailTemplateText.get(objCustSettingCaseName.Name).Closed_Response_Template_Body__c,objCase);
                    objCase.Auto_Case_Closed_Email_Subject__c = parseMergeFields(mapCaseEmailTemplateText.get(objCustSettingCaseName.Name).Auto_Case_Closed_Email_Subject__c,objCase);
                } 
                if(objCase.Manual_Intervention_Not_Required__c){
                    objCase.Status = 'Closed';
                }else{
                    objCase.Status = West_Security_Extensions__c.getInstance(userinfo.getProfileId()).Default_West_Support_Case_Status__c;  
                }
               /* If the Case Priority is not set, update it. */   
               if(objCase.West_Case_Priority_Set__c == false){
                objCase.Priority = objCustSettingCaseName.West_Case_Priority__c;
                objCase.West_Case_Priority_Set__c = true;
               }
                
             /* Update Owner Id */
             if(mapQueueReferenceObject.containsKey(objCase.Queue_Name__c)){
                if(objCase.Status=='New')
                        objCase.OwnerId = mapQueueReferenceObject.get(objCase.Queue_Name__c).QueueId;
             }
             System.debug('Cases details have been updated 2:'+objCase);
         //  }
          }
        }      
    }
    public string parseMergeFields( String pValue,Case objCase ) {
        Boolean isNext = true;
        Integer previousIndex = 0;
        if(pValue==null || pValue ==''){
            return pValue;
        }
        while ( isNext ) {
            if( previousIndex > 0 ) {
                previousIndex = previousIndex + 2;
            }
            previousIndex = pValue.indexOf('{!', previousIndex);
            if( previousIndex == -1 ) {
                isNext = false;
                break;
            } else {
                String tempVariable = pValue.substring(previousIndex + 2, pValue.indexOf('}', previousIndex));
                if( tempVariable != null ) {
                    String tempVariableData = varialbleData(tempVariable,objCase);
                    if( tempVariableData == null ) {
                        tempVariableData = 'Error!!';
                    }
                    pValue = pValue.replaceAll('\\{' + '\\!' + tempVariable + '\\}', tempVariableData);
                } else {
                    pValue = pValue.replaceFirst('{!', '');
                }
            }
        }
        return pValue;
    }
    
    //Added by Sreekanth SV Vegi for email updation from account or lead
  /*  public void EmailfromleadorAccount(List<Case> newCasesList )
    {
        
         //Added by Sreekanth SV Vegi
             for(Case newCaseDetails : newCasesList)
          {              
        if(newCaseDetails.AccountId!=null){
              //Account caseacc=[select id,Personal_Email__pc from Account where id=:newCaseDetails.AccountId limit 1];
             //System.debug('Account id for case ' +caseacc.id);
              //newCaseDetails.Email__c=caseacc.Personal_Email__pc;
              newCaseDetails.Email__c = newCaseDetails.Account.personal_email__pc;
              
            }
        else if(newCaseDetails.Lead__c!=null){
              //Lead caselead=[select id,Email from Lead where id=:newCaseDetails.Lead__c];
              //newCaseDetails.Email__c=caselead.Email;
              newCaseDetails.Email__c = newCaseDetails.Lead__r.Email;
              
              }
        else
            {}
            }
                       
    }*/
    public string varialbleData( String pVariable, Case objCase ) {
        if( pVariable.contains('.') ) {
            if( objCase != null ) {
                String tempField = '';
                if( pVariable.contains('::Date') ) {
                    tempField = pVariable.substring(pVariable.indexOf('.') + 1, pVariable.indexOf('::Date'));
                    return String.valueOf( ((Datetime) objCase.get(tempField)).format('MM/dd/yyyy') );
                } else {
                    tempField = pVariable.substring(pVariable.indexOf('.') + 1, pVariable.length());
                    return String.valueOf( objCase.get(tempField) );
                }
                
            }
        }
        return null;
    }
}